#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：mark_by_line 
@File ：滚动计算平均计划执行率（GUI版本.py
@IDE  ：PyCharm
@Author ：李涵彬
@Date ：2025/1/9 上午10:44
"""

import os.path
import pandas as pd
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from tkcalendar import DateEntry  # 需要安装 tkcalendar 库：pip install tkcalendar


def generate_stats_file(data_source_path, start_date_str, end_date_str=None, output_file_path='统计结果.csv',
						fields_to_analyze=None):
	"""
	生成统计文件。

	参数：
	data_source_path (str): 数据源文件路径。
	start_date_str (str): 统计起始日期，格式为 'YYYY-MM-DD'。
	end_date_str (str, optional): 统计结束日期，格式为 'YYYY-MM-DD'。默认为 None。
	output_file_path (str, optional): 输出统计文件路径。默认为 '统计结果.csv'。
	fields_to_analyze (list, optional): 需要统计的字段列表。默认为 None。
	"""
	print(f'正在处理{data_source_path}，开始生成统计文件{output_file_path}...')

	start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
	if end_date_str is None:
		end_date = start_date + timedelta(days=30)
	else:
		end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()

	df = pd.read_excel(data_source_path, sheet_name='SheetJS')
	df['创建时间'] = pd.to_datetime(df['创建时间'])

	# 处理带有百分号的字段
	for field in fields_to_analyze:
		if field in df.columns and df[field].dtype == object:  # 如果字段是字符串类型
			df[field] = df[field].str.rstrip('%').astype('float')  # 去除百分号并转换为浮点数

	# 根据字段列表进行统计
	stats_data = []
	current_date = start_date
	while current_date <= end_date:
		daily_data = df[(df['创建时间'].dt.date == current_date)]
		plan_count = daily_data.shape[0]

		# 根据字段列表计算平均值
		avg_values = {}
		for field in fields_to_analyze:
			if field in df.columns:
				avg_values[field] = round(daily_data[field].mean(), 2) if not daily_data.empty else 0
			else:
				avg_values[field] = 0  # 如果字段不存在，设置为0

		stats_data.append({
			'序号': len(stats_data) + 1,
			'创建日期': current_date,
			'计划数量': plan_count,
			**avg_values  # 将计算的平均值添加到字典中
		})

		current_date += timedelta(days=1)

	stats_df = pd.DataFrame(stats_data)
	avg_plan_count = round(stats_df['计划数量'].mean(), 2)
	total_plan_count = stats_df['计划数量'].sum()

	# 计算每个字段的平均值
	avg_values_summary = {}
	for field in fields_to_analyze:
		if field in stats_df.columns:
			avg_values_summary[f'平均{field}'] = round(stats_df[field].mean(), 2)
		else:
			avg_values_summary[f'平均{field}'] = 0

	avg_row = pd.DataFrame([{
		'序号': '平均',
		'创建日期': '',
		'计划数量': avg_plan_count,
		**avg_values_summary  # 将每个字段的平均值添加到字典中
	}])

	total_row = pd.DataFrame([{
		'序号': '总计',
		'创建日期': '',
		'计划数量': total_plan_count,
		**{field: '' for field in fields_to_analyze}  # 总计行中字段为空
	}])

	stats_df = pd.concat([stats_df, avg_row, total_row], ignore_index=True)
	stats_df.to_csv(output_file_path, index=False, encoding='utf-8-sig')

	return avg_plan_count, avg_values_summary


def create_param_dict(source_dir, data_source_path, start_date_str, end_date_str):
	"""
	创建参数字典。

	参数：
	source_dir (str): 数据源目录。
	data_source_path (str): 数据源文件名。
	start_date_str (str): 开始日期字符串。
	end_date_str (str): 结束日期字符串。
	"""
	param_dict = {}
	start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
	end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()

	while start_date <= end_date and start_date + timedelta(days=30) <= end_date:
		param_dict[start_date.strftime('%Y-%m-%d')] = f'{source_dir}/{data_source_path}'
		start_date += timedelta(days=1)

	return param_dict


def save_summary_to_csv(summary_data, output_file_path):
	"""
	将汇总数据保存到CSV文件中。

	参数：
	summary_data (list): 汇总数据列表。
	output_file_path (str): 输出文件路径。
	"""
	summary_df = pd.DataFrame(summary_data)
	summary_df.to_csv(output_file_path, index=False, encoding='utf-8-sig')


def main_gui(data_source_path, output_dir, start_date_str, end_date_str, fields_to_analyze):
	"""
	从 GUI 获取参数并执行统计。

	参数：
	data_source_path (str): 数据源文件路径。
	output_dir (str): 输出目录。
	start_date_str (str): 起始日期。
	end_date_str (str): 结束日期。
	fields_to_analyze (list): 需要统计的字段列表。
	"""
	param_dict = create_param_dict(os.path.dirname(data_source_path), os.path.basename(data_source_path),
								   start_date_str,
								   end_date_str)
	summary_data = []

	for key, value in param_dict.items():
		avg_plan_count, avg_values_summary = generate_stats_file(
			value, key, output_file_path=f'{output_dir}/{os.path.basename(data_source_path)}_{key}.csv',
			fields_to_analyze=fields_to_analyze
		)
		summary_data.append({
			'开始日期': key,
			'结束日期': (datetime.strptime(key, '%Y-%m-%d').date() + timedelta(days=30)).strftime('%Y-%m-%d'),
			'平均计划数量': avg_plan_count,
			**avg_values_summary  # 将每个字段的平均值添加到字典中
		})

	print('正在生成汇总统计结果...')
	save_summary_to_csv(summary_data, f'{output_dir}/{os.path.basename(data_source_path)}_汇总统计结果.csv')
	print('统计完成！')
	messagebox.showinfo("完成", "统计完成！")


def create_gui():
	"""
	创建 GUI 界面。
	"""
	# 创建主窗口
	root = tk.Tk()
	root.title("计划执行率统计工具")
	root.geometry("500x400")

	# 默认值
	default_data_source_path = './data/2250计划执行率.xlsx'
	default_output_dir = './result'
	default_start_date = '2024-11-01'
	default_end_date = '2025-01-05'
	default_fields = ['执行率', '排程数量', '自动化率', '智能平均块数']

	# 数据源文件路径
	tk.Label(root, text="数据源文件路径:").grid(row=0, column=0, padx=10, pady=10)
	data_source_path_entry = tk.Entry(root, width=30)
	data_source_path_entry.insert(0, default_data_source_path)
	data_source_path_entry.grid(row=0, column=1, padx=10, pady=10)

	def browse_data_source_path():
		file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
		if file_path:
			data_source_path_entry.delete(0, tk.END)
			data_source_path_entry.insert(0, file_path)

	tk.Button(root, text="浏览", command=browse_data_source_path).grid(row=0, column=2, padx=10, pady=10)

	# 输出目录
	tk.Label(root, text="输出目录:").grid(row=1, column=0, padx=10, pady=10)
	output_dir_entry = tk.Entry(root, width=30)
	output_dir_entry.insert(0, default_output_dir)
	output_dir_entry.grid(row=1, column=1, padx=10, pady=10)

	def browse_output_dir():
		dir_path = filedialog.askdirectory()
		if dir_path:
			output_dir_entry.delete(0, tk.END)
			output_dir_entry.insert(0, dir_path)

	tk.Button(root, text="浏览", command=browse_output_dir).grid(row=1, column=2, padx=10, pady=10)

	# 起始日期
	tk.Label(root, text="起始日期:").grid(row=2, column=0, padx=10, pady=10)
	start_date_entry = DateEntry(root, date_pattern='yyyy-mm-dd')
	start_date_entry.set_date(datetime.strptime(default_start_date, '%Y-%m-%d'))
	start_date_entry.grid(row=2, column=1, padx=10, pady=10)

	# 结束日期
	tk.Label(root, text="结束日期:").grid(row=3, column=0, padx=10, pady=10)
	end_date_entry = DateEntry(root, date_pattern='yyyy-mm-dd')
	end_date_entry.set_date(datetime.strptime(default_end_date, '%Y-%m-%d'))
	end_date_entry.grid(row=3, column=1, padx=10, pady=10)

	# 统计字段选择
	tk.Label(root, text="统计字段:").grid(row=4, column=0, padx=10, pady=10)
	fields_frame = tk.Frame(root)
	fields_frame.grid(row=4, column=1, padx=10, pady=10)

	fields_vars = {}
	for i, field in enumerate(default_fields):
		fields_vars[field] = tk.BooleanVar(value=True)
		tk.Checkbutton(fields_frame, text=field, variable=fields_vars[field]).grid(row=i, column=0, sticky=tk.W)

	# 开始统计按钮
	def start_statistics():
		data_source_path = data_source_path_entry.get()
		output_dir = output_dir_entry.get()
		start_date_str = start_date_entry.get_date().strftime('%Y-%m-%d')
		end_date_str = end_date_entry.get_date().strftime('%Y-%m-%d')
		fields_to_analyze = [field for field, var in fields_vars.items() if var.get()]

		if not os.path.exists(data_source_path):
			messagebox.showerror("错误", "数据源文件路径无效！")
			return
		if not os.path.exists(output_dir):
			messagebox.showerror("错误", "输出目录无效！")
			return
		if not fields_to_analyze:
			messagebox.showerror("错误", "请至少选择一个统计字段！")
			return

		main_gui(data_source_path, output_dir, start_date_str, end_date_str, fields_to_analyze)

	tk.Button(root, text="开始统计", command=start_statistics).grid(row=5, column=1, padx=10, pady=20)

	# 运行主循环
	root.mainloop()


if __name__ == '__main__':
	create_gui()
